home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Chans / slocal / local.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  8.6 KB  |  391 lines

  1. /* local: local delivery channel */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Chans/slocal/RCS/local.c,v 6.0 1991/12/18 20:12:09 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Chans/slocal/RCS/local.c,v 6.0 1991/12/18 20:12:09 jpo Rel $
  9.  *
  10.  * $Log: local.c,v $
  11.  * Revision 6.0  1991/12/18  20:12:09  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. /*********************************************************************\
  19. *                                                                     *
  20. * local channel - deliver to people                                   *
  21. *                                                                     *
  22. \*********************************************************************/
  23.  
  24.  
  25. #include "head.h"
  26. #include "util.h"
  27. #include "prm.h"
  28. #include "q.h"
  29. #include "dr.h"
  30. #include "qmgr.h"
  31. #include <isode/logger.h>
  32. #include <sys/stat.h>
  33. #include <pwd.h>
  34. #include "sys.file.h"
  35.  
  36. #define TESTVERSION
  37.  
  38. extern  char            *quedfldir;
  39. extern  CHAN            *ch_nm2struct ();
  40. extern  char            *mboxname;
  41. extern  char            *delim1;
  42. extern  char            *delim2;
  43.  
  44. static CHAN             *mychan;
  45. static char             *this_msg;
  46. static struct passwd    *pwd;
  47.  
  48. static int              initproc ();
  49. static int        douser ();
  50. static int         deliver ();
  51. static void             dirinit ();
  52. static struct           type_Qmgr_DeliveryStatus *process ();
  53. static Q_struct         Qstruct;
  54. static int         copy ();
  55.  
  56.  
  57.  
  58. /* ---------------------  Begin Routines  --------------------------------- */
  59.  
  60.  
  61.  
  62.  
  63. main (argc, argv)
  64. int     argc;
  65. char    **argv;
  66. {
  67.     char    *p;
  68.  
  69.     p = argv[0];
  70.     if (*p == '/') {
  71.         p = rindex (p, '/');
  72.         p++;
  73.     }
  74.  
  75.  
  76.     /* -- Init the channel - and find out who we are -- */
  77.     chan_init (p);
  78.  
  79.  
  80.     dirinit ();
  81. #ifdef PP_DEBUG
  82.     if (argc > 1 && strcmp (argv[1], "debug") == 0)
  83.         debug_channel_control (argc, argv,
  84.                     initproc, process, NULLIFP);
  85.     else
  86. #endif
  87.         channel_control (argc, argv, initproc, process, NULLIFP);
  88.     exit (0);
  89. }
  90.  
  91.  
  92.  
  93. static int initproc (arg)
  94. struct type_Qmgr_Channel *arg;
  95. {
  96.     char    *p;
  97.  
  98.     p = qb2str (arg);
  99.  
  100.     PP_TRACE (("initproc (%s)", p));
  101.     if ((mychan = ch_nm2struct (p)) == NULLCHAN)
  102.         err_abrt (RP_PARM, "Channel '%s' not known", p);
  103.  
  104.     PP_NOTICE (("Starting %s (%s)",
  105.             mychan -> ch_name, mychan -> ch_show));
  106.  
  107.     if (p)
  108.         free (p);
  109.  
  110.     return OK;
  111. }
  112.  
  113.  
  114.  
  115.  
  116. static struct type_Qmgr_DeliveryStatus *process (arg)
  117. struct type_Qmgr_ProcMsg *arg;
  118. {
  119.     struct type_Qmgr_UserList *up;
  120.     struct prm_vars         prm;
  121.     Q_struct                *qp = &Qstruct;
  122.     ADDR                    *ad_sendr = NULL,
  123.                 *ad_recip = NULL;
  124.     int                     ad_count,
  125.                 retval;
  126.  
  127.  
  128.     bzero ((char *)&prm, sizeof prm);
  129.     bzero ((char *)qp, sizeof *qp);
  130.  
  131.     if (this_msg)
  132.         free (this_msg);
  133.  
  134.     this_msg = qb2str (arg -> qid);
  135.  
  136.     PP_NOTICE (("Processing msg %s", this_msg));
  137.  
  138.     delivery_init (arg -> users);
  139.  
  140.     retval = rd_msg (this_msg, &prm, qp, &ad_sendr, &ad_recip, &ad_count);
  141.     if (rp_isbad (retval)) {
  142.         PP_LOG (LLOG_EXCEPTIONS, ("local/rd_msg err: %s", this_msg));
  143.         return delivery_setall (int_Qmgr_status_messageFailure);
  144.     }
  145.  
  146.     for (up = arg -> users; up; up = up -> next) {
  147.         retval = douser (up -> RecipientId -> parm, ad_recip,
  148.                  this_msg);
  149.         if (rp_isbad (retval))
  150.             break;
  151.     }
  152.  
  153.     rd_end();
  154.     prm_free (&prm);
  155.     q_free (qp);
  156.  
  157.     return deliverystate;
  158. }
  159.  
  160.  
  161.  
  162. /*
  163. Change into pp queue space
  164. */
  165.  
  166. static void dirinit ()
  167. {
  168.     PP_TRACE (("dirinit ()"));
  169.     if (chdir (quedfldir) < 0)
  170.         err_abrt (RP_LIO, "Uanble to change directory to '%s'",
  171.                         quedfldir);
  172. }
  173.  
  174.  
  175. /*
  176.  * process one extension-id for this message
  177.  */
  178.  
  179. static int douser (rno, ad_recip, msgd)
  180. int     rno;
  181. ADDR    *ad_recip;
  182. char    *msgd;
  183. {
  184.     ADDR    *ap;
  185.  
  186.     PP_TRACE (("douser (%d, ad_recip, %s)", rno, msgd));
  187.  
  188.     for (ap = ad_recip; ap ; ap = ap->ad_next) {
  189.         if (ap-> ad_status == AD_STAT_DONE)
  190.             continue;
  191.         if ( rno == ap -> ad_no)
  192.             return (deliver (ap, msgd));
  193.     }
  194.  
  195.     PP_LOG (LLOG_EXCEPTIONS,
  196.         ("local/user not recipient of %s", this_msg));
  197.  
  198.     delivery_set (rno, int_Qmgr_status_messageFailure);
  199.     return RP_MECH;
  200. }
  201.  
  202.  
  203. static char    *formatdir = NULLCP;
  204.  
  205. /*
  206. Do the delivery
  207. */
  208. static int deliver (ap, msgd)
  209. ADDR    *ap;
  210. char    *msgd;
  211. {
  212.     char    *username = NULLCP,
  213.         *diry = NULLCP,
  214.         *mbox = NULLCP,
  215.         mailbox[MAXPATHLENGTH],
  216.         filename[MAXPATHLENGTH];
  217.     int     first = 0,
  218.         retval;
  219.     RP_Buf  rps,
  220.         *rp = &rps;
  221.  
  222.  
  223.     PP_TRACE (("local/deliver msgd=%s", msgd));
  224.  
  225.     if (ap->ad_outchan->li_chan != mychan) {
  226.         PP_LOG (LLOG_EXCEPTIONS,
  227.             ("local/this extension-id (%d) is not for this chan",
  228.             ap->ad_extension));
  229.         delivery_set (ap -> ad_no, int_Qmgr_status_messageFailure);
  230.         return RP_BAD;
  231.     }
  232.  
  233.     if (tb_getlocal (ap -> ad_r822adr, mychan, &username,
  234.             &diry, &mbox) != OK) {
  235.         PP_LOG (LLOG_EXCEPTIONS,
  236.             ("User %s not registered in chan %s table",
  237.             ap -> ad_r822adr, mychan -> ch_name));
  238.         set_1dr (&Qstruct, ap -> ad_no, this_msg,
  239.              DRR_UNABLE_TO_TRANSFER,
  240.              DRD_UA_UNAVAILABLE,
  241.              "User not registered in delivery table");
  242.         if (!rp_isbad(wr_q2dr (&Qstruct, this_msg)))
  243.             delivery_set (ap -> ad_no, 
  244.                       int_Qmgr_status_negativeDR);
  245.         return RP_USER;
  246.     }
  247.  
  248.     PP_TRACE (("Found entry  for '%s' uid '%s' directory '%s'",
  249.         ap -> ad_r822adr, username, diry));
  250.  
  251.     if (pwd && strcmp (pwd -> pw_name, username) == 0)
  252.         PP_TRACE (("Same user"));
  253.     else {
  254.         if (pwd)
  255.             (void) loc_end ();
  256.  
  257.         if ((pwd = getpwnam (username)) == NULL) {
  258.             PP_LOG (LLOG_EXCEPTIONS,
  259.                 ("local/user '%s' not in passwd file",
  260.                  username));
  261.             set_1dr (&Qstruct, ap -> ad_no, this_msg,
  262.                 DRR_UNABLE_TO_TRANSFER,
  263.                 DRD_UA_UNAVAILABLE,
  264.                 "user not registered in passwd file");
  265.             if (!rp_isbad(wr_q2dr (&Qstruct, this_msg))) 
  266.                 delivery_set (ap -> ad_no,
  267.                           int_Qmgr_status_negativeDR);
  268.             return RP_USER;
  269.         }
  270.  
  271.         if (rp_isbad (loc_init (pwd, diry ? diry : pwd->pw_dir))) {
  272.             PP_LOG (LLOG_EXCEPTIONS, ("loc_init error"));
  273.             delivery_set (ap -> ad_no,
  274.                     int_Qmgr_status_mtaFailure);
  275.             return RP_MECH;
  276.         }
  277.  
  278.     }
  279.  
  280.     /*
  281.     Find the correctly formatted version of the message
  282.     */
  283.  
  284.     if (qid2dir (this_msg, ap, TRUE, &formatdir) == NOTOK) {
  285.         PP_LOG (LLOG_EXCEPTIONS,
  286.             ("Can't locate message %s", this_msg));
  287.         delivery_set (ap -> ad_no, int_Qmgr_status_messageFailure);
  288.         return RP_MECH;
  289.     }
  290.         PP_DBG (("local: mboxname : '%s'", mboxname));
  291.         PP_DBG (("local: delim1   : '%s'", delim1));
  292.         PP_DBG (("local: delim2   : '%s'", delim2));
  293.  
  294.     (void) sprintf (mailbox, "%s/%s",
  295.                 diry ? diry : pwd->pw_dir,
  296.                 mbox ? mbox : mboxname);
  297.  
  298.     PP_TRACE (("delivering to mailbox='%s'", mailbox));
  299.  
  300.     if (loc_open (mailbox, "a", 1, rp) != RP_OK) {
  301.         PP_LOG (LLOG_EXCEPTIONS, ("Can't open mailbox %s",
  302.                       rp -> rp_line));
  303.         delivery_set (ap -> ad_no, int_Qmgr_status_mtaFailure);
  304.         return RP_MECH;
  305.     }
  306.  
  307.     if (rp_isbad (retval = msg_rinit (formatdir))) {
  308.         PP_LOG (LLOG_EXCEPTIONS, ("local/msg_rinit can't init %s",
  309.                   formatdir));
  310.         (void) loc_close (rp);
  311.         delivery_set (ap -> ad_no, int_Qmgr_status_messageFailure);
  312.         return RP_MECH;
  313.     }
  314.  
  315.     PP_TRACE (("Mailbox opened"));
  316.  
  317.     if (loc_write (delim1, strlen (delim1), rp) != RP_OK) {
  318.         PP_LOG (LLOG_EXCEPTIONS,
  319.             ("loc_write can't write delim1 [%s]",
  320.              rp -> rp_line));
  321.         delivery_set (ap -> ad_no, int_Qmgr_status_mtaFailure);
  322.         return rp -> rp_val;
  323.     }
  324.  
  325.     first = 0;
  326.     while ((retval = msg_rfile (filename)) == RP_OK) {
  327.         if (rp_isbad (retval = copy (filename)))
  328.             break;
  329.         if (first++ == 0)
  330.             loc_write ("\n", 1, rp);
  331.     }
  332.  
  333.     if (loc_write (delim2, strlen (delim2), rp) != RP_OK)
  334.         PP_LOG (LLOG_EXCEPTIONS, ("loc_write can't write delim2 [%s]",
  335.                   rp -> rp_line));
  336.  
  337.     loc_close (rp);
  338.  
  339.     retval = msg_rend ();
  340.     if (retval != RP_OK) {
  341.         delivery_set (ap -> ad_no, int_Qmgr_status_mtaFailure);
  342.         return retval;
  343.     }
  344.  
  345.     PP_NOTICE ((">>> local : Message delivered to %s", username));
  346.     if (ap -> ad_usrreq == AD_USR_CONFIRM ||
  347.         ap -> ad_mtarreq == AD_MTA_CONFIRM ||
  348.         ap -> ad_mtarreq == AD_MTA_AUDIT_CONFIRM) {
  349.         set_1dr (&Qstruct, ap -> ad_no, this_msg,
  350.              DRR_NO_REASON,
  351.             -1, NULLCP);
  352.         if (!rp_isbad(wr_q2dr (&Qstruct, this_msg)))
  353.             delivery_set (ap -> ad_no, 
  354.                       int_Qmgr_status_positiveDR);
  355.     }
  356.     else {
  357.         (void) wr_ad_status (ap, AD_STAT_DONE);
  358.         delivery_set (ap -> ad_no, int_Qmgr_status_success);
  359.     }
  360.     return RP_OK;
  361. }
  362.  
  363.  
  364. static int copy (fname)
  365. char    *fname;
  366. {
  367.     FILE    *ifp;
  368.     char    buf[BUFSIZ];
  369.     int     n, retval = RP_OK;
  370.     RP_Buf rps, *rp = &rps;
  371.  
  372.     PP_TRACE (("copy (%s, fp)", fname));
  373.  
  374.     if ((ifp = fopen (fname,"r")) == NULL) {
  375.         PP_LOG (LLOG_EXCEPTIONS,
  376.             ("local/can't read file '%s'", fname));
  377.         return (RP_FOPN);
  378.     }
  379.  
  380.     while ((n = fread (buf, sizeof (char), sizeof (buf), ifp)) > 0)
  381.         if (loc_write (buf, n, rp) != RP_OK) {
  382.             PP_LOG (LLOG_EXCEPTIONS,
  383.                 ("loc_write can't write error [%s]",
  384.                  rp -> rp_line));
  385.             retval = rp -> rp_val;
  386.             break;
  387.         }
  388.     (void) fclose (ifp);
  389.     return (retval);
  390. }
  391.